<?php

namespace cainiao;

use catcher\CatchResponse;
use GuzzleHttp\Exception\RequestException;
use think\Exception;
use think\helper\Str;
use think\view\driver\Think;

class Request
{

//    protected $apiUrl = "http://link.cainiao.com/gateway/link.do";
    protected $apiUrl = "https://prelink.cainiao.com/gateway/link.do";
    protected $appSecret = "SbTW9goeyOgbs5Vr49c04O07Tt20u58m";
    protected $cpCode = "7ac4726f88b4da929660d92fa90ca881";
    protected $digest = '';
    protected $toCode = '';
    protected $msgType = '';
    protected $type = '';


    protected $content=[];
    protected $postData = '';

    protected $headers=[];
    protected $options=[];

    public function __construct(array $data = [])
    {
        /*
         * 订单查询
         */
//        $this->content['userId'] = '2206903100025';
//        $this->content['lgOrderCode'] = 'LP00586471430918';
//        $this->content['orderSource'] = 869;//
/*
        //货主ID
        $this->content['ownerUserId'] = '2206903100025';
        $this->content['businessUnitId'] = 'B00016001';
        $this->content['externalOrderCode'] = Str::random(20,1);
        $this->content['orderType'] = 'BONDED_WHS';
        $this->content['storeCode'] = 'BSZXCCS001';
        $this->content['externalShopName'] = '国际日用品商城';
        $this->content['orderSource'] = 869;
        $this->content['orderCreateTime'] = date('Y-m-d H:i:s');
        $this->content['orderPayTime'] = date('Y-m-d H:i:s');
        $this->content['saleMode'] = 1;

        $this->content['receiverInfo'] = [
            'country'=>'CN',
            'province'=>'江苏',
            'city'=>'南京',
            'district'=>'雨花台区',
            'address'=>'大数据产业基地8栋610',
            'name'=>'徐颖',
            'contactNo'=>'15150688887'
        ];//收货人信息

        $this->content['senderInfo'] = [
            'country'=>'CN',
            'province'=>'江苏',
            'city'=>'南京',
            'district'=>'江宁区',
            'address'=>'万达E栋1103',
            'name'=>'王健林',
            'contactNo'=>'15150688887'
        ];//发件人

        $this->content['refunderInfo'] = [
            'country'=>'CN',
            'province'=>'江苏',
            'city'=>'南京',
            'district'=>'江宁区',
            'address'=>'万达E栋1103',
            'name'=>'王健林',
            'contactNo'=>'15150688887'
        ];//退货人信息

        $goodsTotalPrice = 1.05;//商品总价，申报金额
        $coupon = 0;//优惠金额
        $insurance = 0;//保险费
        $postFee = 0;//运费

        $dutiablePrice = dutiablePrice($insurance,$postFee,$goodsTotalPrice) ;//订单完税总价

//        dd($dutiablePrice);

        $customsTax = customsTax($dutiablePrice ,0,1);//关税
        $consumptionTax = consumptionTax($dutiablePrice,$customsTax,0.091,1);//消费税金额
        $vat = vat($dutiablePrice,$customsTax,$consumptionTax,0,1);//增值税

        $totalTax = totalTax($customsTax,$consumptionTax,$vat);//综合税

        $actualPayment = actualPayment($dutiablePrice,$totalTax,$coupon);//消费者实付金额

//        dd($customsTax,$consumptionTax,$vat);

        $this->content['orderItemList'][] = [
                'itemId'=>'610240611644',
                'itemQuantity'=>1,
                'declareInfo'=>[
                    'customsTax'=>priceFormat($customsTax),//商品关税
                    'consumptionTax'=>priceFormat($consumptionTax),//商品消费税
                    'totalTax'=>priceFormat($totalTax),//商品综合税
                    'itemTotalActualPrice'=>priceFormat($goodsTotalPrice),//商品总价优惠后
                    'itemTotalPrice'=>priceFormat($goodsTotalPrice),//商品总价优惠前
                    'vat'=>$vat
                ]
        ];//订单商品列表

        $this->content['orderAmountInfo'] = [
            'dutiablePrice'=>priceFormat($dutiablePrice),//订单完税总价
            'coupon'=>priceFormat($coupon),//优惠金额
            'consumptionTax'=>priceFormat($consumptionTax),//消费税金额
            'postFee'=>priceFormat($postFee),//运费
            'vat'=>priceFormat($vat),//增值税
            'customsTax'=>priceFormat($customsTax),//关税
            'actualPayment'=> priceFormat($actualPayment),//实付金额
            'totalTax'=>priceFormat($totalTax),//综合税金额
            'insurance'=>priceFormat($insurance),//保险费金额
            'currency'=>'CNY'
        ];//订单金额信息

        $this->content['customsDeclareInfo'] = [
            'buyerName'=>'徐颖',
            'buyerPlatformId'=>1,
            'buyerIDType'=>1,
            'buyerIDNo'=>'320923199610233610',
//            'payerId'=>'',
            'payChannel'=>'XSZF',
            'payOrderId'=>'642023070622001443491437819448',//支付单单号
            'nationality'=>"CN",
            'contactNo'=>'15150688887'
        ];//订单申报
//        $this->content['businessUnitId'] = 'B00016001';

//        dd($this->content);
*/
    }

    /**
     * 认证
     * */
    protected function auth(){
        $this->options();

        //签名
        $this->digest = $this->digest();

        $this->postData = $this->postData();
    }

    //签名
    protected function digest(){
        return base64_encode(md5(json_encode($this->content) . $this->appSecret, true));
    }

    //数据
    protected function postData(){

        $post_data = 'msg_type=' . $this->msgType
            .'&logistics_interface='.urlencode(json_encode($this->content))
            .'&data_digest='.urlencode($this->digest)
            .'&logistic_provider_id='.urlencode($this->cpCode);

        if(!empty($this->toCode)){
            $post_data .= '&to_code='. $this->toCode ;
        }
        return $post_data;
    }

    protected function headers(){
        $this->headers=[
//            'Content-Type' => 'application/json',
            'Content-Type' => 'application/x-www-form-urlencoded',
        ];
//        if(!empty($this->key) && !empty($this->secret)) {
//            $this->headers=array_merge($this->headers,[
//                'OK-ACCESS-KEY'=> $this->key,
//                'OK-ACCESS-TIMESTAMP'=>$this->nonce,
//                'OK-ACCESS-PASSPHRASE' =>$this->passphrase,
//                'OK-ACCESS-SIGN' => $this->signature,
//            ]);
//        }
    }

    /**
     *
     * */
    protected function options(){
        if(isset($this->options['headers'])) $this->headers=array_merge($this->headers,$this->options['headers']);

        $this->options['headers']=$this->headers;
        $this->options['timeout'] = $this->options['timeout'] ?? 60;
    }

    /**
     *
     * */
    protected function send(){
        $client = new \GuzzleHttp\Client();

        $url=$this->apiUrl;

        if($this->type=='GET') {
            $url.='?'.http_build_query($this->content);
        }else{
            //$this->options['body']=json_encode($this->postData);
            parse_str($this->postData,$arr);
            //dd($arr);

            $this->options['form_params'] = $arr;
        }

//        dd($this->options);

        /*print_r($this->options);
        die;*/

        $response = $client->request($this->type, $url,$this->options);

        $this->response_headers = $response->getHeaders();

        return $response->getBody()->getContents();
    }

    /*
     *
     * */
    protected function exec(){
        $this->auth();

        try {
            $result = $this->send();

            $xml = @simplexml_load_string($result);

            if ($xml !== false) {
                $result = json_decode(json_encode($xml),true);
            } else {
                $result = json_decode($result,true);
            }

            if( false  !== $result['success']  && 'false' !== $result['success'] ){
                return $result;
            }

            if($result['success'] === "false"){
                throw new Exception($result['errorMsg']);
            }

            throw new Exception($result['errorMsg']);
        }catch (RequestException $e){
            if(empty($e->getResponse()) || $e->getResponse()==null)
                throw new Exception('接口请求失败，没有返回值');

            if(method_exists($e->getResponse(),'getBody')){
                $contents=$e->getResponse()->getBody()->getContents();

                $temp=json_decode($contents,true);
                if(!empty($temp)) {
                    $temp['_method']=$this->type;
                    $temp['_url']=$this->apiUrl;
                }else{
                    $temp['_message']=$e->getMessage();
                }
            }else{
                $temp['_message']=$e->getMessage();
            }

            $temp['_httpcode']=$e->getCode();

//            throw new Exception(json_encode($temp));
            throw new Exception($e->getMessage());
        }
    }

    /**
     * Get Response Headers
     * */
    public function getResponseHeaders(){
        return $this->response_headers;
    }
}